// CPage4.cpp : Implementierungsdatei
//

#include "stdafx.h"
#include "Charplan.h"
#include "CPage4.h"
#include "charplandoc.h"
#include ".\cpage4.h"


// CPage4-Dialogfeld

IMPLEMENT_DYNAMIC(CPage4, CAPage)
CPage4::CPage4(CWnd* pParent /*=NULL*/)
	: CAPage(CPage4::IDD, pParent)
{
}

CPage4::~CPage4()
{
}

void CPage4::DoDataExchange(CDataExchange* pDX)
{
	CAPage::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, mwnd_liste);
	DDX_Control(pDX, IDC_TREE2, mwnd_positions);
	DDX_Control(pDX, IDC_CHECK2, mwnd_showallstyles);
	DDX_Control(pDX, IDC_COMBO1, mwnd_position_choose);
	DDX_Control(pDX, IDC_COMBO4, mwnd_line_filter);
}


BEGIN_MESSAGE_MAP(CPage4, CAPage)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST1, OnNMCustomdrawList1)
	ON_BN_CLICKED(IDC_CHECK2, OnBnClickedCheck2)
	ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelchangeCombo1)
	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE2, OnTvnSelchangedTree2)
	ON_NOTIFY(NM_CLICK, IDC_LIST1, OnNMClickList1)
	ON_CBN_SELCHANGE(IDC_COMBO4, OnCbnSelchangeCombo4)
END_MESSAGE_MAP()



BOOL CPage4::OnInitDialog()
{
	CAPage::OnInitDialog();

	mwnd_liste.InsertColumn(0,_T("Name"));
	mwnd_liste.InsertColumn(1,_T("Level"));
	mwnd_liste.InsertColumn(2,_T("Pre"));
	mwnd_liste.InsertColumn(3,_T("To-Hit"));
	mwnd_liste.InsertColumn(4,_T("Defense"));
	mwnd_liste.InsertColumn(5,_T("Endu"));
	mwnd_liste.InsertColumn(6,_T("Damage"));
	mwnd_liste.InsertColumn(7,_T("Effect"));
	mwnd_liste.InsertColumn(8,_T("Growthrate"));


	// Creating the IMAGELIST (workaround for 32bit)
	m_images.Create(16,16,ILC_MASK | ILC_COLOR32,0,0);
	CBitmap bmp;
	bmp.LoadBitmap(IDB_STYLE_ICONS);
	m_images.Add(&bmp, RGB(255,0,255));
	bmp.DeleteObject();

	mwnd_positions.SetImageList(&m_images,TVSIL_NORMAL);
	mwnd_position_choose.SetImageList(&m_images);
	

	mwnd_liste.SetExtendedStyle(LVS_EX_FULLROWSELECT );

	if (GetDocument()->GetOption(_T("ShowAllStyles")))
		mwnd_showallstyles.SetCheck(true);


	OnClassChanged();


    // Resizer
    static const CResizer::CBorderInfo s_bi[] = {
        {IDC_LIST1, {CResizer::eFixed, IDC_MAIN, CResizer::eLeft},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eTop},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eRight},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eBottom}},
        {IDC_TREE2, {CResizer::eFixed, IDC_LIST1, CResizer::eRight},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eTop},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eRight},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eBottom}},
        {IDC_COMBO1, {CResizer::eFixed, IDC_LIST1, CResizer::eRight},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eTop},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eRight},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eTop}},
        {IDC_COMBO4, {CResizer::eFixed, IDC_LIST1, CResizer::eRight},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eTop},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eRight},
                    {CResizer::eFixed, IDC_MAIN, CResizer::eTop}},
    };
    m_resizer.Init(m_hWnd, NULL, s_bi, sizeof(s_bi)/sizeof(s_bi[0]));


	return TRUE;  
}


void CPage4::OnBnClickedCheck2()
{
	GetDocument()->SetOption(_T("ShowAllStyles"),mwnd_showallstyles.GetCheck());
	OnClassChanged();

}




void	CPage4::FillPositionChooser()
{
	CStringArray stylelines;
	CStringArray styles;
	IntArray	 style_levels;
	IntArray	 style_ids;

	gdbinterface.GetListOfStyleLines(stylelines);

    CString str_all_lines;
    str_all_lines.LoadString(IDS_ALL_STYLE_LINES);
    CString str_temp;


	// Maik Jurkait [7.2.2005]
	//===========================================
	// store old selection
	//===========================================
	int PrePos = 0;
	int cur = mwnd_position_choose.GetCurSel();
	if (cur == CB_ERR) PrePos = -1;
	else PrePos = (int)mwnd_position_choose.GetItemData(cur);

	CString oldline;
	mwnd_line_filter.GetWindowText(oldline);
	if (oldline.IsEmpty()) oldline = str_all_lines;



	// Maik Jurkait [7.2.2005]
	//===========================================
	// reset
	//===========================================
	mwnd_position_choose.ResetContent();
	mwnd_line_filter.ResetContent();
	mwnd_line_filter.AddString(str_all_lines);


	COMBOBOXEXITEM idata;
    str_temp.LoadString(IDS_STYLE_PRE_ALL); // ALL
	idata.mask = CBEIF_LPARAM |  CBEIF_TEXT;
	idata.iItem = mwnd_position_choose.GetCount();
	idata.pszText = (LPSTR)((LPCSTR)str_temp);
	idata.cchTextMax = (int)_tcslen(idata.pszText);
	idata.lParam = -1;
	mwnd_position_choose.InsertItem(&idata);


    str_temp.LoadString(IDS_STYLE_PRE_0);  // ANY
	idata.mask = CBEIF_IMAGE | CBEIF_LPARAM | CBEIF_SELECTEDIMAGE | CBEIF_TEXT;
	idata.iItem = mwnd_position_choose.GetCount();
	idata.pszText = (LPSTR)((LPCSTR)str_temp);
	idata.cchTextMax = (int)_tcslen(idata.pszText);
	idata.iImage = idata.iSelectedImage = 0;
	idata.lParam = 0;
	mwnd_position_choose.InsertItem(&idata);




	//	DWORD dw_view = 0;
	for (int t=0;t<stylelines.GetCount();t++)
	{
		int level = GetDocument()->GetSpecLevel(stylelines[t]);
		if (mwnd_showallstyles.GetCheck()) level = 50;

		mwnd_line_filter.AddString(stylelines[t]);

		gdbinterface.SelectStyleLine(stylelines[t]);
		gdbinterface.GetListOfStyles(&styles,&style_levels,&style_ids);
		for (int t2=0;t2<styles.GetCount();t2++)
		{
			if (style_levels[t2]>level) continue;

			gdbinterface.SelectStyleID(style_ids[t2]);

			int pre = gdbinterface.GetStylePrePos();
            str_temp.Empty();

			switch (pre)
			{
				case 0: continue;
                case 1: str_temp.LoadString(IDS_STYLE_PRE_1); /* Front */ break;
				case 2: str_temp.LoadString(IDS_STYLE_PRE_2); /* Behind */ break;
				case 3: str_temp.LoadString(IDS_STYLE_PRE_3); /* Side */ break;
				case 4: str_temp.LoadString(IDS_STYLE_PRE_4); /* after Evade */ break;
				case 5: str_temp.LoadString(IDS_STYLE_PRE_5); /* after Block */ break;
				case 6: str_temp.LoadString(IDS_STYLE_PRE_6); /* after Parry */ break;
				case 7: str_temp.LoadString(IDS_STYLE_PRE_7); /* Target */ break;
				case 8: continue; // PreStyle
				case 9: continue; // Ability
				case 128: continue;
				case 129: str_temp.LoadString(IDS_STYLE_PRE_S1); /* Front (Stealthed) */ break;
				case 130: str_temp.LoadString(IDS_STYLE_PRE_S2); /* Behind  (Stealthed) */ break;
				case 131: str_temp.LoadString(IDS_STYLE_PRE_S3); /* Side  (Stealthed) */ break;
				case 132: str_temp.LoadString(IDS_STYLE_PRE_S4); /* after Evade  (Stealthed) */ break;
				case 133: str_temp.LoadString(IDS_STYLE_PRE_S5); /* after Block  (Stealthed) */ break;
				case 134: str_temp.LoadString(IDS_STYLE_PRE_S6); /* after Parry  (Stealthed) */ break;
				case 135: str_temp.LoadString(IDS_STYLE_PRE_S7); /* Target  (Stealthed) */ break;

				default:
						ASSERT(false);
			}

            idata.pszText = (LPSTR)((LPCSTR)str_temp);

			if (mwnd_position_choose.FindStringExact(-1,idata.pszText)!=CB_ERR ) continue;



			// Find Insert Position (sort by front,behind,....)
			const int order[200]=
				{
					0,1,3,5,7,9,11,13,15,0,    0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
					0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
					2,4,6,8,10,12,14,16,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
				};

			int pos = 2; // skip any+all
			for (;pos<mwnd_position_choose.GetCount();pos++)
			{
				if (order[pre]<order[ mwnd_position_choose.GetItemData(pos)])  break;
			}

	
			idata.mask = CBEIF_IMAGE | CBEIF_LPARAM | CBEIF_SELECTEDIMAGE | CBEIF_TEXT;
			idata.iItem = pos;//mwnd_position_choose.GetCount();
			idata.lParam = pre;
			if (pre>127) pre += 8-128;
			idata.iImage = idata.iSelectedImage = pre;
			idata.cchTextMax = (int)_tcslen(idata.pszText);
			mwnd_position_choose.InsertItem(&idata);
		}
	}



	// select
	int pos = 0;
	for (pos=0;pos<mwnd_position_choose.GetCount();pos++)
		if ((int)mwnd_position_choose.GetItemData(pos)==PrePos) break;

	mwnd_line_filter.SelectString(-1,oldline);


	mwnd_positions.DeleteAllItems();
	if (pos<mwnd_position_choose.GetCount())
	{
		mwnd_position_choose.SetCurSel(pos);
		FillPositionTree();
	}
}



void CPage4::OnCbnSelchangeCombo1()
{
	FillPositionTree();
}

void CPage4::OnCbnSelchangeCombo4()
{
	FillPositionTree();
}


void	CPage4::FillPositionTree()
{
	int PrePos = 0;
	int cur = mwnd_position_choose.GetCurSel();
	if (cur == CB_ERR) PrePos = -1;
	else PrePos = (int)mwnd_position_choose.GetItemData(cur);

    CString str_all_lines;
    str_all_lines.LoadString(IDS_ALL_STYLE_LINES);

	CString linefilter;
	mwnd_line_filter.GetWindowText(linefilter);
	if (linefilter == str_all_lines) linefilter.Empty();



	CStringArray stylelines;
	CStringArray styles;
    IntArray     style_levels;
    IntArray     style_ids;

	mwnd_positions.DeleteAllItems();

	gdbinterface.GetListOfStyleLines(stylelines);

	for (int t=0;t<stylelines.GetCount();t++)
	{
		int level = GetDocument()->GetSpecLevel(stylelines[t]);
		if (mwnd_showallstyles.GetCheck()) level = 50;


		if (!linefilter.IsEmpty() && linefilter != stylelines[t]) continue;


		gdbinterface.SelectStyleLine(stylelines[t]);
		gdbinterface.GetListOfStyles(&styles,&style_levels,&style_ids);
		for (int t2=0;t2<styles.GetCount();t2++)
		{
			if (style_levels[t2]>level) continue;

			gdbinterface.SelectStyleID(style_ids[t2]);

			int pre = gdbinterface.GetStylePrePos();
			if ((pre&127) == 8)
			{
				// get PrePos of First parent
				int parent2 = gdbinterface.GetStylePreStyleID();
				while (parent2>=0)
				{
					gdbinterface.SelectStyleID(parent2);
					parent2 = gdbinterface.GetStylePreStyleID();
				}
				pre = gdbinterface.GetStylePrePos();
				gdbinterface.SelectStyleID(style_ids[t2]);
			}

			// any, selected and no abilities
			if ((PrePos!=-1 && PrePos!=pre) || ((pre&127)== 9)) continue;

			

			int	pre_style = gdbinterface.GetStylePreStyleID();
			HTREEITEM pos = TVI_ROOT;
			if (pre_style>=0)
			{
				pre_style = -1-(pre_style | (gdbinterface.GetStyleLineID()<<16));

				// find position
				pos = TreeFindItem(&mwnd_positions, pre_style);
				ASSERT(pos); // parent not in tree
				if (!pos) pos = TVI_ROOT;
			}

			if (pre>127) pre += 8-128;
			HTREEITEM it = mwnd_positions.InsertItem(styles[t2],pre,pre,pos);
			mwnd_positions.SetItemData(it,-1- (gdbinterface.GetStyleID() | (gdbinterface.GetStyleLineID()<<16)));
		}
	}

}



HTREEITEM	CPage4::TreeFindItem(CTreeCtrl*ctrl, DWORD_PTR id, HTREEITEM start /*= TVI_ROOT*/)
{
 	HTREEITEM result = ctrl->GetNextItem(start,TVGN_CHILD );
	if (result == NULL) return NULL;

	do
	{
		if (ctrl->ItemHasChildren(result) )
		{
			HTREEITEM i = TreeFindItem(ctrl, id, result);
			if (i) return i;
		}

		if (ctrl->GetItemData(result) == id) return result;

		result = ctrl->GetNextItem(result,TVGN_NEXT );
	} while (result != NULL);

	return NULL;
}


void CPage4::OnTvnSelchangedTree2(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

	*pResult = 0;

	DWORD selected_id = (DWORD) (mwnd_positions.GetItemData(pNMTreeView->itemNew.hItem));

	for (int t=0;t<mwnd_liste.GetItemCount();t++)
	{
		if (mwnd_liste.GetItemData(t)==selected_id)
		{
			
			//	Clear old selections
			POSITION pos = mwnd_liste.GetFirstSelectedItemPosition();
		    while (pos)
			{
				 int nItem = mwnd_liste.GetNextSelectedItem(pos);
				 mwnd_liste.SetItemState(nItem,0,LVIS_SELECTED);
			}

			// select
			mwnd_liste.EnsureVisible(t,false);
			mwnd_liste.SetItemState(t,LVIS_SELECTED,LVIS_SELECTED);
			return;
		}
	}
}

HTREEITEM	CPage4::FindInPosTree(HTREEITEM hb, DWORD_PTR id)
{
	HTREEITEM hi = mwnd_positions.GetChildItem(hb);
	while (hi)
	{
		if (mwnd_positions.GetItemData(hi) == id) return hi;

		HTREEITEM h = FindInPosTree(hi,id);
		if (h) return h;

		hi = mwnd_positions.GetNextSiblingItem(hi);
	}

	return NULL;
}



void CPage4::OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	UNREFERENCED_PARAMETER(pNMHDR);

	int selection = mwnd_liste.GetSelectionMark();
	if (selection != -1)
	{
		DWORD_PTR id = mwnd_liste.GetItemData(selection);

		HTREEITEM hItem = FindInPosTree(TVI_ROOT,id);
	
		if (hItem != NULL)
		{
			HTREEITEM hi = mwnd_positions.GetParentItem(hItem);
			while (hi)
			{
				mwnd_positions.Expand(hi,TVE_EXPAND);
				hi = mwnd_positions.GetParentItem(hi);
			}

			mwnd_positions.Select(hItem,TVGN_CARET);
			mwnd_positions.EnsureVisible(hItem);

		}
		
	}
	*pResult = 0;
}



void CPage4::OnLevelChanged()
{
	if (GetDocument()->IsCarrerMode() && !mwnd_showallstyles.GetCheck())
		OnClassChanged();
}

// CPage4-Meldungshandler
void CPage4::OnClassChanged()
{
	mwnd_liste.DeleteAllItems();



	CStringArray stylelines;
	CStringArray styles;
	IntArray	 style_levels;
    IntArray	 style_ids;
	CStringArray properties_names;
	CStringArray properties_vals;

	gdbinterface.GetListOfStyleLines(stylelines);

	bool show_all = (BST_CHECKED == mwnd_showallstyles.GetCheck());

	if (IsWindowVisible()) SetRedraw(FALSE);
	for (int t=0;t<stylelines.GetCount();t++)
	{
		// 
		int level = GetDocument()->GetSpecLevel(stylelines[t]);
		//if (show_all) level = 50;

		gdbinterface.SelectStyleLine(stylelines[t]);

		mwnd_liste.InsertItem(LVIF_TEXT|LVIF_PARAM,
								mwnd_liste.GetItemCount(),stylelines[t],
								0,0,0,1);

		gdbinterface.GetListOfStyles(&styles,&style_levels,&style_ids);
		for (int t2=0;t2<styles.GetCount();t2++)
		{
			if (style_levels[t2]>level && !show_all) continue;

			gdbinterface.SelectStyleID(style_ids[t2]);
			gdbinterface.GetStyleDescription(properties_names,properties_vals);

			int item = mwnd_liste.InsertItem(mwnd_liste.GetItemCount(),styles[t2]);

			
			// we have to work with that "-1-.." stuff 'cause param is additional used for coloring
			mwnd_liste.SetItemData(item,-1- (gdbinterface.GetStyleID() | (gdbinterface.GetStyleLineID()<<16)));

			CString temp; temp.Format(_T("%i"),style_levels[t2]);
			mwnd_liste.SetItemText(item,1,temp);

			for (int t4=2;t4<properties_names.GetCount();t4++)
			{
				mwnd_liste.SetItemText(item,t4,properties_vals[t4]);
			}
		}
	}

	for (int t=0;t<mwnd_liste.GetHeaderCtrl()->GetItemCount();t++)
		mwnd_liste.SetColumnWidth(t,LVSCW_AUTOSIZE);

	SetRedraw(TRUE);
	Invalidate();

	FillPositionChooser();

	mn_last_viewed_description = -1;
}


void CPage4::OnNMCustomdrawList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMLVCUSTOMDRAW  lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;

	*pResult = CDRF_DODEFAULT;
	switch(lplvcd->nmcd.dwDrawStage)
	{
		case CDDS_PREPAINT:
			*pResult = CDRF_NOTIFYITEMDRAW;          // ask for item notifications.
			break;

		case CDDS_ITEMPREPAINT:
			*pResult = CDRF_DODEFAULT;

			switch (lplvcd->nmcd.lItemlParam)
			{
				case 1:
					lplvcd->clrTextBk = RGB(196, 196, 255);
					break;
				case 2:
					lplvcd->clrTextBk = RGB(212, 212, 212);
					break;
				case 3:
					lplvcd->clrText = RGB(212, 212, 212);
					break;
			}
			break;
	}
}


void	CPage4::SetupToolTips()
{
	CAPage::SetupToolTips();


	// Abilities
	mToolTips.AddTool(&mwnd_liste,CString(""));

	mToolTips.AddTool(&mwnd_showallstyles, _T("if selected all styles will be displayed.<br>Otherwise it displays only skilled styles."));

}




BOOL CPage4::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
	if (message != LVN_MOUSEMOVE)
		return CAPage::OnWndMsg(message, wParam, lParam, pResult);

	int item = LOWORD(wParam);
	if (item == -1)
	{
		if (mn_last_viewed_description != -1)	
			mToolTips.UpdateTipText(CString(""),&mwnd_liste);
		mn_last_viewed_description = -1;
		return TRUE;
	}
	
	item = (int)mwnd_liste.GetItemData(item);
	if (item >=0)
	{
		if (mn_last_viewed_description != -1)	
			mToolTips.UpdateTipText(CString(""),&mwnd_liste);
		mn_last_viewed_description = -1;
		return TRUE;
	}


	item = -item-1;

	if (mn_last_viewed_description != item)	
	{
		mn_last_viewed_description = item;

		int style = item &0xffff;
		// int styleline = item >>16;

        CString text = gdbinterface.GetStyleDetailtext(style);


		mToolTips.UpdateTipText(text,&mwnd_liste);
	}

	return TRUE;
}





